package com.yan.club.sys.control;

import com.github.pagehelper.PageInfo;
import com.yan.club.auth.model.LoginUser;
import com.yan.club.auth.utils.SecurityUtil;
import com.yan.club.result.Result;
import com.yan.club.sys.dto.LoginDto;
import com.yan.club.sys.dto.SysRoleDto;
import com.yan.club.sys.dto.SysUserDto;
import com.yan.club.sys.model.SysCommunity;
import com.yan.club.sys.model.SysRole;
import com.yan.club.sys.model.SysUser;
import com.yan.club.sys.service.SysCommunityService;
import com.yan.club.sys.service.SysRoleService;
import com.yan.club.sys.service.SysUserService;
import com.yan.club.sys.vo.LoginUserVo;
import com.yan.club.sys.vo.SysUserVo;
import com.yan.club.sys.vo.SysVo;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import static com.github.pagehelper.page.PageMethod.startPage;
import static com.yan.club.auth.utils.SecurityUtil.*;
import static com.yan.club.result.ResultCode.INTERNAL_SERVER_ERROR;

/**
 * @author 彦
 * @since 2024/2/6 21:49
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController {

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysCommunityService sysCommunityService;

    @Resource
    private SysRoleService sysRoleService;

    /**
     * 登录
     */
    @PostMapping("/login")
    public Result<LoginUserVo> login(@RequestBody LoginDto loginDto) {
        return sysUserService.login(loginDto);
    }

    /**
     * 退出登录
     */
    @PostMapping("/logout")
    public Result<String> logout() {
        return sysUserService.logout();
    }

    @GetMapping("/getInfo")
    public Result<SysVo> getInfo() {
        // 得到当前登录的用户
        LoginUser loginUser = getLoginUser();

        // 根据用户id查询角色信息
        List<String> roleKeys = sysUserService.selectRoleKeyByUserId(loginUser.getUser().getUserId());

        // 根据用户id查询权限信息
        List<String> perms = sysUserService.selectPermsByUserId(loginUser.getUser().getUserId());

        LoginUserVo loginUserVo = new LoginUserVo();
        BeanUtils.copyProperties(loginUser.getUser(), loginUserVo);
        loginUserVo.setPermissions(loginUser.getPermissions());

        SysVo sysVo = new SysVo(perms, roleKeys, loginUserVo);

        return Result.success(sysVo);
    }

    /**
     * 获取用户列表
     */
    @PreAuthorize("@check.hasAuthority('system:user:list')")
    @GetMapping("/list")
    public Result<PageInfo<SysUser>> list(SysUserDto user) {
        startPage(user.getPageNum(), user.getPageSize(), true);
        List<SysUser> list = sysUserService.selectUserList(user);
        return Result.success(new PageInfo<>(list));
    }

    /**
     * 获取部门树列表
     */
    @PreAuthorize("@check.hasAuthority('system:user:list')")
    @GetMapping("/deptTree")
    public Result<List<SysCommunity>> deptTree(SysCommunity sysCommunity) {
        return Result.success(sysCommunityService.selectDeptTreeList(sysCommunity));
    }

    /**
     * 根据用户编号获取详细信息
     */
    @PreAuthorize("@check.hasAuthority('system:user:query')")
    @GetMapping(value = {"/", "/{userId}"})
    public Result<SysUserVo> getInfoById(@PathVariable(value = "userId", required = false) Long userId) {
        sysUserService.checkUserDataScope(userId);

        SysUserVo sysUserVo = new SysUserVo();

        List<SysRole> roles = sysRoleService.selectRoleList(new SysRoleDto());
        // 除了超级管理员以为的角色
        List<SysRole> sysRoles = isAdmin(userId) ? roles :
                roles.stream().filter(r -> !isAdmin(r.getRoleId())).collect(Collectors.toList());
        sysUserVo.setRoles(sysRoles);

        if (userId != null) {
            SysUser sysUser = sysUserService.selectUserById(userId);
            // 得到自己当前的角色
            Long[] roleIds = sysUser.getRoles().stream()
                    .map(SysRole::getRoleId).toArray(Long[]::new);
            sysUserVo.setSysUser(sysUser);
            sysUserVo.setRoleIds(roleIds);
        }

        return Result.success(sysUserVo);
    }

    /**
     * 新增用户
     */
    @PreAuthorize("@check.hasAuthority('system:user:add')")
    @PostMapping
    public Result<String> add(@Validated @RequestBody SysUser user) {
        if (sysUserService.checkUserNameUnique(user)) {
            return Result.error(INTERNAL_SERVER_ERROR.code, "新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && sysUserService.checkPhoneUnique(user)) {
            return Result.error(INTERNAL_SERVER_ERROR.code, "新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail()) && sysUserService.checkEmailUnique(user)) {
            return Result.error(INTERNAL_SERVER_ERROR.code, "新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setCreateBy(getUser().getUserName());
        user.setPassword(SecurityUtil.encryptPassword(user.getPassword()));
        return sysUserService.insertUser(user);
    }

    /**
     * 修改用户
     */
    @PreAuthorize("@check.hasAuthority('system:user:edit')")
    @PutMapping
    public Result<String> edit(@Validated @RequestBody SysUser user) {
        sysUserService.checkUserAllowed(user);
        sysUserService.checkUserDataScope(user.getUserId());
        if (sysUserService.checkUserNameUnique(user)) {
            return Result.error(INTERNAL_SERVER_ERROR.code, "修改用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && sysUserService.checkPhoneUnique(user)) {
            return Result.error(INTERNAL_SERVER_ERROR.code, "修改用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail()) && sysUserService.checkEmailUnique(user)) {
            return Result.error(INTERNAL_SERVER_ERROR.code, "修改用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setUpdateBy(getUser().getUserName());
        return sysUserService.updateUser(user);
    }

    /**
     * 删除用户
     */
    @PreAuthorize("@check.hasAuthority('system:user:remove')")
    @DeleteMapping("/{userIds}")
    public Result<String> remove(@PathVariable Long[] userIds) {
        if (ArrayUtils.contains(userIds, getUserId())) {
            return Result.error(INTERNAL_SERVER_ERROR.code, "当前用户不能删除");
        }
        return sysUserService.deleteUserByIds(userIds);
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@check.hasAuthority('system:user:edit')")
    @PutMapping("/changeStatus")
    public Result<String> changeStatus(@RequestBody SysUser user) {
        sysUserService.checkUserAllowed(user);
        sysUserService.checkUserDataScope(user.getUserId());
        user.setUpdateBy(getUser().getUserName());
        return sysUserService.updateUserStatus(user);
    }

    /**
     * 根据用户编号获取授权角色
     */
    @PreAuthorize("@check.hasAuthority('system:user:query')")
    @GetMapping("/authRole/{userId}")
    public Result<SysUserVo> authRole(@PathVariable("userId") Long userId) {
        SysUser user = sysUserService.selectUserById(userId);
        List<SysRole> roles = sysRoleService.selectRolesByUserId(userId);

        SysUserVo sysUserVo = new SysUserVo();
        sysUserVo.setSysUser(user);

        List<SysRole> sysRoles = isAdmin(userId) ? roles :
                roles.stream().
                        filter(r -> !isAdmin(r.getRoleId()))
                        .collect(Collectors.toList());
        sysUserVo.setRoles(sysRoles);

        return Result.success(sysUserVo);
    }

    /**
     * 用户授权角色
     */
    @PreAuthorize("@check.hasAuthority('system:user:edit')")
    @PutMapping("/authRole")
    public Result<String> insertAuthRole(Long userId, Long[] roleIds) {
        sysUserService.checkUserDataScope(userId);
        sysUserService.insertUserAuth(userId, roleIds);
        return Result.success();
    }

    @PreAuthorize("@check.hasAuthority('system:user:export')")
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysUser user) {
        List<SysUser> list = sysUserService.selectUserList(user);
        sysUserService.export(response, list);
    }

    /**
     * 导入
     *
     * @param file
     * @return
     * @throws Exception
     */
    @PreAuthorize("@check.hasAuthority('system:user:import')")
    @PostMapping("/importData")
    public Result<String> importData(@RequestPart("file") MultipartFile file) throws Exception {
        return sysUserService.importData(file);
    }

    /**
     * 下载模板
     *
     * @param response
     * @throws IOException
     */
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) throws IOException {
        sysRoleService.importTemplate(response);
    }

}
